package com.ruoyi.controller.jpjs.progressplan;

import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.base64.Base64Util;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.domain.jpjs.common.progressplan.*;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.service.jpjs.concrete.ConcreteService;
import com.ruoyi.service.jpjs.progressplan.ProgressplanService;
import com.ruoyi.system.service.ISysDictDataService;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.utils.DateUtils.getDate;

/**
 * @author C.fw
 * @explain 进度计划控制层
 * @since 2021/2/22 10:15
 */
@SuppressWarnings("ALL")
@Controller
@RequestMapping("/progressplan")
public class ProgressplanController extends BaseController {

    private String prefix = "jpjs/progressplan";

    @Autowired
    private ProgressplanService progressplanService;

    @Autowired
    private ConcreteService concreteService;

    @Autowired
    private ISysDictDataService sysDictDataService;

    /**
     * 首页面
     */
    @GetMapping()
    public String View(ModelMap mmp, Progressplan progressplan) {
        mmp.put("node", sysDictDataService.selectDictDataByType("node_name"));
        mmp.put("programName", progressplan.getProgramName());
        mmp.put("batch", progressplan.getBatch());
        mmp.put("nodeId", progressplan.getNode());
        mmp.put("programId", progressplan.getProgramId());
        mmp.put("buildingNumber", progressplan.getBuildingNumber());
        return prefix + "/list";
    }

    /**
     * 首页面: 获取列表数据
     */
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(@RequestParam Map<String, Object> map) {
        startPage();
        map.put("programName", map.get("programName").toString().trim().replaceAll(",", ""));
        map.put("userId", ShiroUtils.getSysUser().getUserId());

        // 总计数据
        List<Progressplan> list = progressplanService.selectProgressList(map);

        // 计算节点完成率
        // Step2 初始化 数值格式化对象
        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(2);
        String finishRate;
        String isEffectFlag = "0";

        // Step3 获取完成节点集合
        List<Progressplan> finishedList = new ArrayList<>();
        if (StringUtils.isNotEmpty(list)) {
            for (Progressplan progress : list) {
                progress.setIsEffectFlag("0");

                if (progress.getStatus().equals("完成")) {
                    finishedList.add(progress);
                }
            }
            int totalSize = list.size();
            int finishSize = finishedList.size();
            finishRate = numberFormat.format((float) finishSize / (float) totalSize * 100);
        } else {
            finishRate = "0";
        }


        if (StringUtils.isNotEmpty(list)) {
            for (Progressplan progress : list) {
                progress.setMsgInfo(finishRate);
            }
        } else {
            for (Progressplan progress : list) {
                progress.setMsgInfo("0");
            }
        }

//         Step3 是否生效(有一个不生效,都默认为不生效)
        if (StringUtils.isNotEmpty(list)) {
            for (Progressplan progress : list) {
                // 0 生效 1 不生效
                if (progress.getIsEffect().equals("1")) {
                    for (Progressplan proObj : list) {
                        proObj.setIsEffectFlag("1");
                    }
                    break;
                }
            }
        }

        // 初始化数据
        return getProDataTable(progressplanService.loopFormatData(list), finishRate, isEffectFlag);
    }

    /**
     * 首页面: 根据选中项目,获取项目楼栋号
     */
    @GetMapping("/selectBuildingNumber")
    @ResponseBody
    public List selectBuildingNumber(String companyId, String proId) {
        Map<String, Object> map = new HashMap<>();
        map.put("companyId", companyId);
        map.put("proId", proId);
        List<Map<String, Object>> maps = concreteService.selectBuildingNumberList(map);
        return maps;
    }


    /**
     * 新增页面
     */
    @GetMapping("/addView")
    public String addView(ModelMap mmp, String companyId, String proId) {
        Map<String, Object> map = new HashMap<>();
        map.put("companyId", companyId);
        map.put("proId", proId);
        mmp.put("companyId", companyId);
        mmp.put("programId", proId);
        mmp.put("floorNumber", sysDictDataService.selectDictDataByType("floor_number"));
        mmp.put("buildingNumber", concreteService.selectBuildingNumberList(map));
        mmp.put("node", sysDictDataService.selectDictDataByType("node_name"));
        return prefix + "/add";
    }

    /**
     * 新增、编辑页面 根据楼栋号获取楼层号
     */
    @GetMapping("/selectFloorNumber")
    @ResponseBody
    public Map selectFloorNumber(String companyId, String proId, String buildingNumber) {
        Map<String, Object> map = new HashMap<>();
        map.put("companyId", companyId);
        map.put("programId", proId);
        map.put("buildingNumber", buildingNumber);
        Map<String, Object> resultMap = progressplanService.selectProgressById(map);
        return resultMap;
    }

    /**
     * 新增页面:保存
     */
    @PostMapping("/save")
    @ResponseBody
    public AjaxResult save(Progressplan progressplan) {
        // 判断新增用户的角色
        if (ShiroUtils.getSysUser().getUserName().equals("ggAdmin")) {
            progressplan.setIsEffect("0");
        } else {
            progressplan.setIsEffect("1");
        }

        progressplan.setCreater(ShiroUtils.getSysUser().getUserName());
        // 工程公司、项目名称、楼栋号、节点名称唯一性校验
        if (progressplanService.checkNodeUnique(progressplan)) {
            return new AjaxResult(AjaxResult.Type.WARN, MessageUtils.message("progress.info.unique"));
        }
        return toAjax(progressplanService.addProgress(progressplan));
    }

    /**
     * 首页面:导出
     */
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(@RequestParam Map<String, Object> map) {
        List<Progressplan> list = progressplanService.selectProgressList(map);
        ExcelUtil<Progressplan> util = new ExcelUtil<Progressplan>(Progressplan.class);
        return util.exportExcel(progressplanService.loopFormatData(list), "进度计划管理");
    }

    /**
     * 编辑页面
     */
    @RequiresRoles("ggzxadmin")
    @GetMapping("/editView")
    public String editView(ModelMap mmp, String progressId, String companyId, String programId) {

        // Step1 获取当前详情信息
        Map<String, Object> map = new HashMap<>();
        map.put("companyId", companyId);
        map.put("proId", programId);
        map.put("progressId", progressId);
        Map progressMap = progressplanService.selectProgressById(map);
        Integer nodeId = Integer.valueOf(progressMap.get("nodeId").toString());
        progressMap.put("nodeId", nodeId);

        // Step2 初始化列表数据
        mmp.put("progress", progressMap);
        mmp.put("buildingNumber", concreteService.selectBuildingNumberList(map));
        mmp.put("node", sysDictDataService.selectDictDataByType("node_name"));
        mmp.put("floorNumber", sysDictDataService.selectDictDataByType("floor_number"));
        return prefix + "/edit";
    }

    /**
     * 编辑页面:保存
     */
    @PostMapping("/editSave")
    @ResponseBody
    public AjaxResult editSave(Progressplan progressplan) {
        // 编辑保存之前数据处理
        if (progressplanService.handleEdit(progressplan)) {
            return new AjaxResult(AjaxResult.Type.WARN, MessageUtils.message("progress.info.unique"));
        }
        return toAjax(progressplanService.updateProgressById(progressplan));
    }

    /**
     * 首页面:删除
     */
    @RequiresRoles("ggzxadmin")
    @PostMapping("/remove")
    @ResponseBody
    public AjaxResult remove(String ids) {
        try {
            return toAjax(progressplanService.deleteProgressById(ids));
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 进度计划页面:跳转动态管理详情页面
     */
    @GetMapping("/detail")
    public String detail(ModelMap mmap, Progressplan progressplan) {
        // 业务参数 回显
        mmap.put("progressId", progressplan.getProgressId());
        mmap.put("planEndTime", progressplan.getPlanEndTime());

        // 查询参数 返回携带
        mmap.put("programName", progressplan.getProgramName());
        mmap.put("batch", progressplan.getBatch());
        mmap.put("node", progressplan.getNode());
        mmap.put("programId", progressplan.getProgramId());
        mmap.put("buildingNumber", progressplan.getBuildingNumber());

        return prefix + "/detail";
    }

    /**
     * 动态管理详情页面:获取数据列表
     */
    @PostMapping("/detailList")
    @ResponseBody
    public TableDataInfo selectExcellenceList(ProgressplanDetail progressplanDetail) {
        startPage();
        Map<String, Object> map = new HashMap<>();
        map.put("progressId", progressplanDetail.getProgressId());
        List<ProgressplanDetail> list = progressplanService.selectDetailListByProgressId(map);
        return getDataTable(list);
    }

    /**
     * 动态详情页面 新增页面
     */
    @GetMapping("/detailAddView")
    public String detailAdd(Progressplan progressplan, ModelMap mmap) {
        // 新增页面 初始化数据
        List<ProgressplanRemark> remarkList = progressplanService.readyForAddView(progressplan);
        if (StringUtils.isNotEmpty(remarkList)) {
            mmap.put("remarkList", remarkList);
        }
        mmap.put("progressplan", progressplan);
        return prefix + "/detailAdd";
    }


    /**
     * 动态详情新增页面:新增详情
     */
    @PostMapping("/saveDetail")
    @ResponseBody
    public AjaxResult saveDetail(ProgressplanDetailParam progressplanDetailParam) throws IOException {
        // 新增保存前 校验和新增进度详情
        if (progressplanService.handleDataForSave(progressplanDetailParam)) {
            return new AjaxResult(AjaxResult.Type.WARN, MessageUtils.message("progress.info.finish"));
        }

        // 判断是否存在图片
        if (StringUtils.isNotEmpty(progressplanDetailParam.getFile())) {
            // Step1 物理上传
            MultipartFile multipartFile = Base64Util.base64ToMultipart(progressplanDetailParam.getFile());
            String fileName = FileUploadUtils.upload(Global.getUploadPath(), multipartFile);
            // Step1.2 参数准备
            // 物理路径,用于物理删除
            progressplanDetailParam.setPhysicalPath(getPhysicalPath(Global.getUploadPath(), fileName));
            // 文件名,用于下载
            progressplanDetailParam.setFileName(fileName);
            // 虚拟路径,用于展示
            progressplanDetailParam.setVirtualPath(ServerConfig.getUrl() + fileName);
        }

        return toAjax(progressplanService.addProgressDetail(progressplanDetailParam));
    }

    /**
     * 查询进度情况描述
     */
    @GetMapping("/detailRemark/{progressId}")
    public String detailRemark(@PathVariable("progressId") Long progressId, ModelMap mmap) {
        Map<String, Object> map = new HashMap<>();
        mmap.put("progressId", progressId);
        return prefix + "/remark";
    }

    /**
     * 跳转描述详情: 获取详情列表
     */
    @PostMapping("/remarkList")
    @ResponseBody
    public TableDataInfo remarlList(@RequestParam Map<String, Object> map) {
        startPage();
        List<ProgressplanRemark> list = progressplanService.selectRemarksByProgressId(map);
        return getDataTable(list);
    }

    /**
     * 描述详情页面:导出
     */
    @PostMapping("/exportRemark")
    @ResponseBody
    public AjaxResult exportRemark(@RequestParam Map<String, Object> map) {
        List<ProgressplanRemark> list = progressplanService.selectRemarksByProgressId(map);
        ExcelUtil<ProgressplanRemark> util = new ExcelUtil<ProgressplanRemark>(ProgressplanRemark.class);
        return util.exportExcel(list, "进度情况详情");
    }

    private String getPhysicalPath(String filePath, String fileName) {
        String replace = fileName.replace("/profile/upload", "");
        String physicalPath = filePath + replace;
        return physicalPath;
    }

    /**
     * 首页面 上传效果图页面
     */
    @GetMapping("/uploadView")
    public String uploadView(Progressplan progressplan, ModelMap mmap) {
        // 新增页面 初始化数据
        mmap.put("progressplan", progressplan);
        return prefix + "/upload";
    }

    /**
     * 首页面 查看效果概况
     */
    @GetMapping("/checkView")
    public String checkView(Progressplan progressplan, ModelMap mmap) {
        // 查看页面 初始化数据
        Map<String, Object> map = new HashMap<>();
        map.put("programId", progressplan.getProgramId());
        mmap.put("progressplan", progressplanService.selectImg(map));
        return prefix + "/checkUpload";
    }

    /**
     * 详情页面 新增保存
     */
    @PostMapping("/upload")
    @ResponseBody
    public AjaxResult updateAvatar(@RequestParam("file") MultipartFile file, Progressplan progressplan) {
        try {

            // Step1 物理上传
            String fileName = FileUploadUtils.upload(Global.getUploadPath(), file);
            // 虚拟路径,用于展示
            progressplan.setViPath(ServerConfig.getUrl() + fileName);

            // Step2 新增并响应
            return toAjax(progressplanService.addProgressImg(progressplan));
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 编辑删除附件
     */
    @RequestMapping("/deletePic")
    @ResponseBody
    public AjaxResult deletePic(Progressplan progressplan) {

        // Step1 根据ID进行物理删除
        Boolean flag = progressplanService.deleteFilePathById(Integer.valueOf(progressplan.getKey()));

        // Setp2 更新数据库响应
        if (flag) {
            return AjaxResult.success(progressplanService.updatePathById(Integer.valueOf(String.valueOf(progressplan.getKey()))));
        }
        return AjaxResult.error("失败");
    }


    @PostMapping("/statisticList")
    @ResponseBody
    public TableDataInfo statisticList(Progressplan progre) {
        NumberFormat nt = NumberFormat.getPercentInstance();//获取格式化对象

        // Step1 参数准备 获取分组项目ID
        List<Progressplan> progressList = progressplanService.queryProjectGroupByProgram();

        if (StringUtils.isNotEmpty(progressList)) {
            for (Progressplan progress : progressList) {

                List<Progressplan> progressplans = progressplanService.queryProgramList();
                if (StringUtils.isNotEmpty(progressplans)) {

                    // Step2 月份准备
                    // Step2.1 获取yyyy-MM格式月份(未分组)
                    List<Progressplan> dataList = new ArrayList<>();
                    for (int i = 0; i < progressplans.size(); i++) {
                        if (progress.getProgramId().equals(progressplans.get(i).getProgramId())) {
                            progressplans.get(i).setPlanEndTime(progressplans.get(i).getPlanEndTime().substring(0, progressplans.get(i).getPlanEndTime().lastIndexOf('-')));
                            Progressplan planObj = new Progressplan();
                            planObj.setProgramId(progressplans.get(i).getProgramId());
                            planObj.setPlanMonth(progressplans.get(i).getPlanEndTime());
                            dataList.add(planObj);
                        }
                    }

                    // Step2.2 月份去重yyyy-MM
                    List<Progressplan> planList = dataList
                            .stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getPlanMonth()))), ArrayList::new))
                            .stream().sorted(Comparator.comparing(Progressplan::getPlanMonth))
                            .collect(Collectors.toList());

                    // Step2.3 月份倒序排列
                    List<Progressplan> collect = planList.stream().sorted(Comparator.comparing(Progressplan::getPlanMonth).reversed()).collect(Collectors.toList());

                    // Step3 计划完成率(从最大月低依次获取)
                    // Step3.1  确定分母,需统计总数 获取最大月底时间(yyyy-MM-dd)
                    Map<String, Object> mapParamTotal = new HashMap<>();
                    mapParamTotal.put("planEndTime", DateUtils.getMonthEnd(collect.get(0).getPlanMonth()));
                    mapParamTotal.put("programId", collect.get(0).getProgramId());
                    List<Progressplan> progresTotalList = progressplanService.queryPlanFinishRate(mapParamTotal);
                    int totalNum = progresTotalList.size();

                    // Step3.2 确定分子,需统计每个月需完成的节点数量
                    for (int i = 0; i < collect.size(); i++) {
                        Map<String, Object> param = new HashMap<>();
                        param.put("planEndTime", DateUtils.getMonthEnd(collect.get(i).getPlanMonth()));
                        param.put("programId", collect.get(i).getProgramId());
                        List<Progressplan> progresList = progressplanService.queryPlanFinishRate(param);
                        if (StringUtils.isNotEmpty(progresList)) {
                            int planFinishNum = progresList.size();
                            // 四舍五入取百分比
                            String planFinishRate = getPercentage(totalNum, planFinishNum);
                            collect.get(i).setPlanFinishRate(planFinishRate);
                        }

                        String nowStr = getDate();
                        // 测试月底,后续删除
//                        String nowStr ="2021-04-30";
//                        String nowStr ="2021-05-09";

                        // 实际完成率
                        // 循环得出的月份
                        String planMon = collect.get(i).getPlanMonth();
                        // 当前的月份
                        DateUtils.getMonth();

                        // 当前月份大于循环月份
                        if (DateUtils.getMonthSub(planMon, DateUtils.getMonth()) >= 0) {
//                            if (DateUtils.getMonthSub(planMon, "2021-05") >= 0) {
                            Map<String, Object> mapPara = new HashMap<>();
                            mapPara.put("programId", collect.get(i).getProgramId());
                            mapPara.put("planEndTime", nowStr);
                            List<Progressplan> progres = progressplanService.queryActualRate(mapPara);
                            if (StringUtils.isNotEmpty(progres)) {
//                                if (DateUtils.getMonth().equals(nowStr.substring(0, 4))) {
                                if (DateUtils.getMonth().equals(nowStr.substring(0, 4))) {
                                    BigDecimal bg = new BigDecimal(Double.valueOf(progres.size()) / Double.valueOf(progresTotalList.size()));
                                    String actualFinishRate = nt.format(bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                                    collect.get(i).setActualFinishRate(actualFinishRate);
                                } else {
                                    // 取当天月份的最后一天
//                                        String nowDay2 ="2021-05-09";
                                    String nowDay2 = DateUtils.getDate();
                                    // 获取yyyy-MM格式,月底一天
                                    String monthEndDay2 = DateUtils.getMonthEnd(nowDay2);
                                    param.put("planTime", monthEndDay2);

                                    List<Progressplan> progressObj = progressplanService.queryDynamicRate(param);
                                    if (StringUtils.isNotEmpty(progressObj)) {
                                        BigDecimal bg = new BigDecimal(Double.valueOf(progressObj.size()) / Double.valueOf(progresTotalList.size()));
                                        String actualFinishRate = nt.format(bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());


                                        // 判断当前日期是否是月底最后一天
                                        String nowDay11 = DateUtils.getDate();
//                                        String nowDay11 = "2021-04-30";
//                                        String nowDay11 ="2021-05-09";

                                        // 获取yyyy-MM格式,月底一天
                                        String monthEndDay = DateUtils.getMonthEnd(nowDay11);
                                        // 如果是月底最后一天,保存到实际完成率及动态完成率 否则保存动态完成率
                                        if (nowDay11.equals(monthEndDay)) {
                                            collect.get(i).setActualFinishRate(actualFinishRate);
                                            collect.get(i).setActualTempFinishRate(actualFinishRate);
                                        } else {
                                            collect.get(i).setActualTempFinishRate(actualFinishRate);
                                        }
                                    } else {
                                        collect.get(i).setActualFinishRate("-");
                                        collect.get(i).setActualTempFinishRate("-");
                                    }
                                }
                            }
                        }

                        for (Progressplan progObj : collect) {
                            if (StringUtils.isNotEmpty(progObj.getActualFinishRate())) {
                                progObj.setActualTempFinishRate(progObj.getActualFinishRate());
                            }
                            if (StringUtils.isEmpty(progObj.getActualTempFinishRate())) {
                                progObj.setPlanOffset(progObj.getPlanFinishRate());
                            } else {
                                Integer planRate = Integer.parseInt(progObj.getPlanFinishRate().replace("%", ""));
                                Integer actualRate = Integer.parseInt(progObj.getActualTempFinishRate().replace("%", ""));
                                progObj.setPlanOffset(String.valueOf(planRate - actualRate) + "%");
                            }
                        }
                    }

                    // 实际完成率保持月底记录
                    List<Progressplan> progressplanList = progressplanService.queryStatisticList(progre);
                    if (StringUtils.isNotEmpty(progressplanList)) {
                        for (Progressplan progressplan : progressplanList) {
                            String actualFinishRate = progressplan.getActualFinishRate();
                            if (StringUtils.isNotEmpty(actualFinishRate)) {
                                // 将原先月底完成率保存给新增的
                                for (Progressplan pro : collect) {
                                    if (progressplan.getPlanMonth().equals(pro.getPlanMonth())) {
                                        pro.setActualFinishRate(progressplan.getActualFinishRate());
                                    }
                                }
                            }
                        }
                    }
                    // 删除统计表数据
                    Progressplan progressplan = new Progressplan();
                    progressplan.setProgramId(progress.getProgramId());
                    progressplanService.deleteStatisticByProgramId(progressplan);
                    progressplanService.insertStatisticBatches(collect);
                }
            }
        }

        List<Progressplan> progressplanListAll = progressplanService.queryStatisticList(progre);
        for (Progressplan progressplan : progressplanListAll) {
            if (StringUtils.isNotEmpty(progressplan.getActualFinishRate())) {
                progressplan.setActualTempFinishRate(progressplan.getActualFinishRate());
                Integer planRate = Integer.parseInt(progressplan.getPlanFinishRate().replace("%", ""));
                Integer actualRate = Integer.parseInt(progressplan.getActualFinishRate().replace("%", ""));
                progressplan.setPlanOffset(String.valueOf(planRate - actualRate) + "%");
            }
        }
        return getDataTable(progressplanListAll);
    }

    private String getPercentage(int totalNum, int planFinishNum) {
        NumberFormat nt = NumberFormat.getPercentInstance();
        BigDecimal bg = new BigDecimal(Double.valueOf(planFinishNum) / Double.valueOf(totalNum));
        return nt.format(bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
    }

    /**
     * 改变项目动态 状态(sh)
     *
     * @param progressplan
     * @return
     */

    @RequiresRoles("ggzxadmin")
    @PostMapping("/changeStatus")
    @ResponseBody
    public AjaxResult changeStatus(Progressplan progressplan) {
        return toAjax(progressplanService.updateStatusByProgramId(progressplan));
    }

    /**
     * 首页面:导出
     */
    @PostMapping("/exportStatistic")
    @ResponseBody
    public AjaxResult exportStatistic(@RequestParam Map<String, Object> map) throws IOException {
        List<ProgressplanStatistic> list = progressplanService.queryStatisticListExport(map);
        for (ProgressplanStatistic progressplan : list) {
            if (StringUtils.isNotEmpty(progressplan.getActualFinishRate())) {
                progressplan.setActualTempFinishRate(progressplan.getActualFinishRate());
                Integer planRate = Integer.parseInt(progressplan.getPlanFinishRate().replace("%", ""));
                Integer actualRate = Integer.parseInt(progressplan.getActualFinishRate().replace("%", ""));
                progressplan.setPlanOffset(String.valueOf(planRate - actualRate) + "%");
            }
        }
        ExcelUtil<ProgressplanStatistic> util = new ExcelUtil<ProgressplanStatistic>(ProgressplanStatistic.class);
        return util.exportExcel(list, "项目统计");
    }

}
